defmodule FileHandling do
  def read_lines filename do
    File.stream!(filename)
    |> Stream.map(&String.trim_trailing/1)
  end
end


defmodule RockPaperScissors do
  def outcome(:rock, :rock) do :draw end
  def outcome(:rock, :paper) do :win end
  def outcome(:rock, :scissors) do :loss end

  def outcome(:paper, :rock) do :loss end
  def outcome(:paper, :paper) do :draw end
  def outcome(:paper, :scissors) do :win end

  def outcome(:scissors, :rock) do :win end
  def outcome(:scissors, :paper) do :loss end
  def outcome(:scissors, :scissors) do :draw end

  def outcome_score(:loss) do 0 end
  def outcome_score(:draw) do 3 end
  def outcome_score(:win) do 6 end

  def choice_score(:rock) do 1 end
  def choice_score(:paper) do 2 end
  def choice_score(:scissors) do 3 end

  def input_to_rps("A") do :rock end
  def input_to_rps("B") do :paper end
  def input_to_rps("C") do :scissors end
  def input_to_rps("X") do :rock end
  def input_to_rps("Y") do :paper end
  def input_to_rps("Z") do :scissors end

  def round_to_rps([p1_input, p2_input]) do
    {input_to_rps(p1_input), input_to_rps(p2_input)}
  end
  def round_score({p1, p2}) do
    (outcome(p1, p2) |> outcome_score) + (choice_score p2)
  end
  def line_score(line) do
    String.split(line, " ") |> round_to_rps |> round_score
  end
end


# Need to wrap the code in a function to be able to see the struct.
defmodule Main do
  def main do
    lines_stream = FileHandling.read_lines "input"
    result = lines_stream
    |> Stream.map(&RockPaperScissors.line_score/1)
    |> Enum.to_list
    |> Enum.sum

    IO.puts "total score: #{result}"
  end
end

Main.main
